package dominion.kingdom;

import static dominion.CardTypes.Copper;
import static dominion.CardTypes.Duchy;
import static dominion.CardTypes.Estate;
import static dominion.CardTypes.Gold;
import static dominion.CardTypes.Province;
import static dominion.CardTypes.Remodel;
import static dominion.CardTypes.Silver;

import java.util.Collections;
import java.util.Comparator;
import java.util.EnumMap;
import java.util.Map;

import dominion.Action;
import dominion.Card;
import dominion.CardTypes;
import dominion.Dominion;
import dominion.Player;
import dominion.Tresure;
import dominion.Victory;

public class Remodel implements Action {

	static final Map<CardTypes, Integer> cardRank = new EnumMap<CardTypes, Integer>(
			CardTypes.class);
	static {
		CardTypes[] rank = { Estate, Copper, Duchy, Silver, Gold };
		for (int i = 0; i < rank.length; i++) {
			cardRank.put(rank[i], i);
		}
	}

	@Override
	public void execute(Dominion dominion) {
		Player player = dominion.current();
		int tresure = player.tresure();
		Collections.sort(player.hand(), new Comparator<Card>() {
			@Override
			public int compare(Card l, Card r) {
				Integer li = cardRank.get(l.getType());
				Integer ri = cardRank.get(r.getType());
				if (li == null) {
					li = 10;
				}
				if (ri == null) {
					ri = 10;
				}
				return li - ri;
			}
		});
		for (Card c : player.hand()) {
			if (Estate.equals(c.getType())) {
				player.gain(new Remodel());
				player.trash(c);
				player.hand().remove(c);
				break;
			}
			if (Copper.equals(c.getType())) {
				if (tresure == 4 || tresure == 5 || tresure == 7 || 8 < tresure) {
					player.gain(Victory.ESTATE);
					player.trash(c);
					player.hand().remove(c);
					break;
				}
			}
			if (Remodel.equals(c.getType()) && 2 < player.count(Remodel)) {
				player.gain(Tresure.GOLD);
				player.trash(c);
				player.hand().remove(c);
				break;
			}
			if (Gold.equals(c.getType()) && 2 < player.count(Province)) {
				player.gain(Victory.PROVINCE);
				player.trash(c);
				player.hand().remove(c);
				break;
			}
		}
	}

	@Override
	public CardTypes getType() {
		return Remodel;
	}

	@Override
	public String toString() {
		return Remodel.name();
	}
}
